package org.niux.aims.dao.impl;

import java.util.List;
import java.util.logging.Level;

import javax.persistence.EntityManager;
import javax.persistence.Query;

import org.niux.aims.dao.IEntitysDAO;
import org.niux.aims.models.EntityManagerHelper;
import org.niux.aims.models.Entitys;
import org.springframework.stereotype.Repository;

/**
 * 
 * Copyright (c) 2009,niux<br>
 * All rights reserved.<br>
 * 
 * 文件名称：EntitysDAO.java<br>
 * 摘    要：实体数据操作类<br>
 * <br>
 * 当前版本：<br>
 * 作    者：铭显 Email: <a href="mailto:liangmingxian@gmail.com">liangmingxian@gmail.com</a><br>
 * 完成日期：@since 2013-8-1<br>
 * <br>
 * 取代版本：<br>
 * 原作者  ：<br>
 * 完成日期：@since Oct 22, 2009<br>
 */
@Repository(value="entityDao")
public class EntitysDAO implements IEntitysDAO {
	// property constants
	public static final String ENTITY_NAME = "entityName";
	public static final String ENTITY_CODE = "entityCode";

	private EntityManager getEntityManager() {
		return EntityManagerHelper.getEntityManager();
	}

	/**
	 * 
	 * 方法概述：新增实体
	 * 描述：新增实体
	 * @param entity
	 * 返回类型：
	 * 修改人：梁铭显
	 * 修改时间：2013-8-18
	 */
	public void save(Entitys entity) {
		try {
//			EntityManagerHelper.beginTransaction();
			getEntityManager().getTransaction().begin();
			getEntityManager().persist(entity);
			getEntityManager().getTransaction().commit();
			
//			getEntityManager().setFlushMode(FlushModeType.COMMIT);
			
//			getEntityManager().;
//			EntityManagerHelper.commit();
			
		} catch (RuntimeException re) {
			throw re;
		}
	}

	/**
	 * 
	 * 方法概述：删除实体
	 * 描述：删除实体
	 * @param entity
	 * 返回类型：
	 * 修改人：梁铭显
	 * 修改时间：2013-8-20
	 */
	public void delete(Entitys entity) {
		try {
			entity = findById(entity.getId());
			entity.getApplication().getEntityses().clear();
			
			if(entity.getEntitys() != null){
				entity.getEntitys().getEntityses().clear();
			}
			
			entity.getEntityType().getEntityses().clear();
			
			getEntityManager().getTransaction().begin();
			getEntityManager().remove(entity);
			getEntityManager().getTransaction().commit();
		} catch (RuntimeException re) {
			throw re;
		}
	}

	/**
	 * 
	 * 方法概述：修改实体
	 * 描述：修改实体
	 * @param entity
	 * @return
	 * 返回类型：
	 * 修改人：梁铭显
	 * 修改时间：2013-8-20
	 */
	public Entitys update(Entitys entity) {
		try {
			EntityManagerHelper.beginTransaction();
			Entitys result = getEntityManager().merge(entity);
			EntityManagerHelper.commit();
			return result;
		} catch (RuntimeException re) {
			throw re;
		}
	}

	/**
	 * 
	 * 方法概述：根据ID获取实体
	 * 描述：根据ID获取实体
	 * @param id
	 * @return
	 * 返回类型：
	 * 修改人：梁铭显
	 * 修改时间：2013-8-20
	 */
	public Entitys findById(Integer id) {
		try {
//			Entitys instance = getEntityManager().find(Entitys.class, id);
			StringBuffer hql = new StringBuffer();
			hql.append("SELECT entitys ");
			hql.append("FROM Entitys entitys ");
			hql.append("LEFT JOIN FETCH entitys.entityType ");
			hql.append("LEFT JOIN FETCH entitys.entitys ");
			hql.append("LEFT JOIN FETCH entitys.application ");
			hql.append("LEFT JOIN FETCH entitys.auths ");
			hql.append("LEFT JOIN FETCH entitys.entityses ");
			hql.append("WHERE 1 = 1 ");
			hql.append("AND entitys.id = :id ");
			
			Query query = getEntityManager().createQuery(hql.toString());
			
			query.setParameter("id", id);
			return (Entitys)query.getSingleResult();
		} catch (RuntimeException re) {
			throw re;
		}
	}

	/**
	 * Find all Entitys entities with a specific property value.
	 * 
	 * @param propertyName
	 *            the name of the Entitys property to query
	 * @param value
	 *            the property value to match
	 * @param rowStartIdxAndCount
	 *            Optional int varargs. rowStartIdxAndCount[0] specifies the the
	 *            row index in the query result-set to begin collecting the
	 *            results. rowStartIdxAndCount[1] specifies the the maximum
	 *            number of results to return.
	 * @return List<Entitys> found by query
	 */
	@SuppressWarnings("unchecked")
	public List<Entitys> findByProperty(String propertyName,
			final Object value, final int... rowStartIdxAndCount) {
		EntityManagerHelper.log("finding Entitys instance with property: "
				+ propertyName + ", value: " + value, Level.INFO, null);
		try {
			final String queryString = "select model from Entitys model where model."
					+ propertyName + "= :propertyValue";
			Query query = getEntityManager().createQuery(queryString);
			query.setParameter("propertyValue", value);
			if (rowStartIdxAndCount != null && rowStartIdxAndCount.length > 0) {
				int rowStartIdx = Math.max(0, rowStartIdxAndCount[0]);
				if (rowStartIdx > 0) {
					query.setFirstResult(rowStartIdx);
				}

				if (rowStartIdxAndCount.length > 1) {
					int rowCount = Math.max(0, rowStartIdxAndCount[1]);
					if (rowCount > 0) {
						query.setMaxResults(rowCount);
					}
				}
			}
			return query.getResultList();
		} catch (RuntimeException re) {
			EntityManagerHelper.log("find by property name failed",
					Level.SEVERE, re);
			throw re;
		}
	}

	/**
	 * 
	 * 方法概述：根据实体名称获取实体数据
	 * 描述：根据实体名称获取实体数据
	 * @param entityName
	 * @return
	 * 返回类型：List<Entitys>
	 * 修改人：梁铭显
	 * 修改时间：2013-8-25
	 */
	@SuppressWarnings("unchecked")
	public List<Entitys> findByEntityName(String entityName) {
		EntityManagerHelper.log(entityName, Level.INFO, null);
		
		StringBuffer hql = new StringBuffer();
		
		hql.append("SELECT DISTINCT entitys ");
		hql.append("FROM Entitys entitys ");
		hql.append("LEFT JOIN FETCH entitys.entityses page ");
		hql.append("LEFT JOIN FETCH page.entityses button ");
		hql.append("WHERE 1=1 ");
		hql.append("AND (entitys.entityName LIKE :like ");
		hql.append("OR page.entityName LIKE :like ");
		hql.append("OR button.entityName LIKE :like) ");
//		hql.append("AND entitys.entitys=NULL ");
		
		Query query = getEntityManager().createQuery(hql.toString());
		
		query.setParameter("like", "%"+entityName+"%");
		
		return query.getResultList();
//		return findByProperty(ENTITY_NAME, entityName, rowStartIdxAndCount);
	}

	public List<Entitys> findByEntityCode(Object entityCode,
			int... rowStartIdxAndCount) {
		return findByProperty(ENTITY_CODE, entityCode, rowStartIdxAndCount);
	}

	/**
	 * 
	 * 方法概述：获取所有实体数据
	 * 描述：获取所有实体数据
	 * @param rowStartIdxAndCount
	 * @return
	 * 返回类型：
	 * 修改人：梁铭显
	 * 修改时间：2013-8-1
	 */
	@SuppressWarnings("unchecked")
	public List<Entitys> findAll(final int... rowStartIdxAndCount) {
		try {
			final String queryString = "select model from Entitys model";
			Query query = getEntityManager().createQuery(queryString);
			if (rowStartIdxAndCount != null && rowStartIdxAndCount.length > 0) {
				int rowStartIdx = Math.max(0, rowStartIdxAndCount[0]);
				if (rowStartIdx > 0) {
					query.setFirstResult(rowStartIdx);
				}

				if (rowStartIdxAndCount.length > 1) {
					int rowCount = Math.max(0, rowStartIdxAndCount[1]);
					if (rowCount > 0) {
						query.setMaxResults(rowCount);
					}
				}
			}
			return query.getResultList();
		} catch (RuntimeException re) {
			throw re;
		}
	}

	/**
	 * 
	 * 方法概述：分页获取实体数据
	 * 描述：分页获取实体数据
	 * @param startPage
	 * @param pageSize
	 * @return
	 * 返回类型：List<Entitys>
	 * 修改人：梁铭显
	 * 修改时间：2013-8-6
	 */
	@SuppressWarnings("unchecked")
	public List<Entitys> findByPage(int startPage, int pageSize){
		StringBuffer hql = new StringBuffer();
		
		hql.append("SELECT entitys ");
		hql.append("FROM Entitys entitys ");
		hql.append("LEFT JOIN entitys.application application ");
		hql.append("LEFT JOIN entitys.entityType entityType ");
//		hql.append("LEFT JOIN FETCH entitys.entityses entityses ");
//		hql.append("WHERE 1=1 ");
//		hql.append("AND entitys.entitys=NULL ");
		
		Query query = getEntityManager().createQuery(hql.toString());
		
		query.setFirstResult(startPage);
		query.setMaxResults(pageSize);
		
		List<Entitys> entitys = query.getResultList();
		
		return entitys;
	}
	
	/**
	 * 
	 * 方法概述：根据父实体获取实体数据
	 * 描述：根据父实体获取实体数据
	 * @param entity
	 * @return
	 * 返回类型：List<Entitys>
	 * 修改人：梁铭显
	 * 修改时间：2013-8-24
	 */
	@SuppressWarnings("unchecked")
	public List<Entitys> findByParent(Entitys entity){
		StringBuffer hql = new StringBuffer();
		
		hql.append("SELECT entitys ");
		hql.append("FROM Entitys entitys ");
		hql.append("LEFT JOIN entitys.entitys parent ");
		hql.append("WHERE 1=1 ");
		
		if(entity == null){
			hql.append("AND entitys.entitys=NULL ");
		} else {
			hql.append("AND parent.id = " + entity.getId());
		}
		
		Query query = getEntityManager().createQuery(hql.toString());
		
		List<Entitys> entitys = query.getResultList();
		
		return entitys;
	}
	
	/**
	 * 
	 * 方法概述：根据应用获取实体数据
	 * 描述：根据应用获取实体数据
	 * @param appid
	 * @return
	 * 返回类型：List<Entitys>
	 * 修改人：梁铭显
	 * 修改时间：2013-9-4
	 */
	@SuppressWarnings("unchecked")
	public List<Entitys> findByApp(int appid){
		StringBuffer hql = new StringBuffer();
		
		hql.append("SELECT entitys ");
		hql.append("FROM Entitys entitys ");
		hql.append("LEFT JOIN FETCH entitys.application app ");
		hql.append("WHERE 1 = 1 ");
		hql.append("AND app.id = :appid ");
		
		Query query = getEntityManager().createQuery(hql.toString());
		
		query.setParameter("appid", appid);
		
		return query.getResultList();
	}
}